package com.xu.cloud.common.desensitization;

import com.xu.cloud.common.constant.Constant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Objects;

/**
 * 头尾保留位数脱敏规则
 *
 * @author xuguan
 * @since 2025/3/3
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ReserveDigitsDesensitizationRule implements IDesensitizationRule {

    public static final int MASK_SAME_LENGTH_DIGITS = -1;

    public static final ReserveDigitsDesensitizationRule DEFAULT_RULE
            = new ReserveDigitsDesensitizationRule(0, 0, "*", 6);

    /**
     * 头部保留位数
     */
    private int headReserveDigits;

    /**
     * 尾部保留位数
     */
    private int tailReserveDigits;

    /**
     * 脱敏符号
     */
    private String mask;

    /**
     * 脱敏符号位数, -1表示加上掩码长度和输入字符串长度保持一致
     */
    private int maskDigits;

    @Override
    public String desensitization(String source) {
        if (Objects.isNull(source)) {
            return Constant.EMPTY_STRING;
        }
        final int length = source.length();
        if (length <= headReserveDigits) {
            return source;
        }
        if (length <= tailReserveDigits) {
            return source;
        }

        final int subLength = length - headReserveDigits - tailReserveDigits;

        // 剩余长度小于等于0, 不需要脱敏
        if (subLength <= 0) {
            return source;
        }

        // 掩码长度设置为剩余长度或者掩码长度大于剩余长度, 将掩码长度设置为剩余长度
        if (maskDigits == MASK_SAME_LENGTH_DIGITS || maskDigits >= subLength) {
            maskDigits = subLength;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            if (i < headReserveDigits || i >= length - tailReserveDigits) {
                sb.append(source.charAt(i));
            } else {
                // 掩码长度小于剩余长度, 脱敏到掩码长度
                if (i < headReserveDigits + maskDigits) {
                    sb.append(mask);
                }
            }
        }
        return sb.toString();
    }
}
